package com.wsoft.form.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wsoft.constant.FieldKindConstant;
import com.wsoft.core.exception.Asserts;
import com.wsoft.core.handler.ICodeRuleHandler;
import com.wsoft.core.utils.ExcelDataUtil;
import com.wsoft.core.utils.LoginUserUtil;
import com.wsoft.entity.BaseEntity;
import com.wsoft.form.constant.AggregationTypeConstant;
import com.wsoft.form.constant.FieldFilterConstant;
import com.wsoft.form.constant.ObjectDefaultColumnConstant;
import com.wsoft.form.constant.ObjectFieldType;
import com.wsoft.form.dto.*;
import com.wsoft.form.dto.operation.JoinTableDTO;
import com.wsoft.form.dto.operation.OperationFilterDTO;
import com.wsoft.form.dto.operation.OperationOrderDTO;
import com.wsoft.form.dto.operation.OperationTableColumnDTO;
import com.wsoft.form.entity.*;
import com.wsoft.form.enums.FormEnum;
import com.wsoft.form.manager.*;
import com.wsoft.form.mapper.WfFormOperationMapper;
import com.wsoft.form.query.operation.LinkListQuery;
import com.wsoft.form.query.operation.OperationInsertQuery;
import com.wsoft.form.query.operation.OperationListQuery;
import com.wsoft.form.query.operation.OperationUpdateQuery;
import com.wsoft.form.service.IWfFormOperationService;
import com.wsoft.form.util.FormUtil;
import com.wsoft.vo.LoginUserVO;
import kotlin.Triple;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author z001
 * @Date 2024/8/30 14:57
 */
@Service
public class WfFormOperationServiceImpl implements IWfFormOperationService {
    @Resource
    private WfFormDesignManager designManager;
    @Resource
    private WfFormColumnManager columnManager;
    @Resource
    private WfFormTableManager tableManager;
    @Resource
    private WfFormOperationMapper operationMapper;
    @Resource
    private WfFormVirtualColumnManager virtualColumnManager;
    @Resource
    private WfFormTableRelationManager relationManager;
    @Resource
    private WfFormColumnLinkManager linkManager;
    @Resource
    private ICodeRuleHandler codeRuleHandler;
//    @Resource
//    private CodeRulesUtil codeRulesUtil;

    /**
     * link表 字段拼接后缀
     */
    private final String LINK_COLUMN_SUFFIX = "_link";

    /**
     * 保存数据
     */
    @Override
    public void addOperation(OperationInsertQuery query) {
        JSONObject data = query.getData();
        //保存子表 判断 需要赋值父id
        if (FormEnum.ZERO.getValue().equals(query.getIsMaster())) {
            if (ObjectUtil.isEmpty(query.getMasterId())) {
                //新增子表的时候 父id 不能为空
                Asserts.fail("[wform.masterId.error.empty]");
            }
            //新增子表
            WfFormDesignEntity designEntity = designManager.getById(query.getDesignId());
            WfFormTableRelationEntity relationEntity = relationManager.getMasterTable(designEntity.getFormId(), designEntity.getTableId(), null);
            WfFormColumnEntity columnEntity = columnManager.getById(relationEntity.getSlaveColumnId());
            //找到外键 并赋值
            data.put(columnEntity.getColumnName(), query.getMasterId());
        }
        WfFormDesignEntity designEntity = designManager.getById(query.getDesignId());

        //保存数据
        addOperation(designEntity.getTableId(), data);
    }

    /**
     * 跟新数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOperation(OperationUpdateQuery query) {
        updateOperation(query.getDesignId(), query.getData());
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delOperation(Long designId, List<Long> dataId) {
        //逻辑删除 调用update方法
        WfFormDesignEntity designEntity = designManager.getById(designId);
        Long tableId = designEntity.getTableId();
        WfFormTableEntity tableEntity = tableManager.getById(tableId);
        operationMapper.delById(tableEntity.getTableName(), dataId);
        //级联删除
        WfFormTableRelationEntity masterTable = relationManager.getMasterTable(designEntity.getFormId(), tableId, FormEnum.ONE.getValue());
        if (null != masterTable) {
            //是主表,需要删除从表数据
            List<WfFormTableRelationEntity> masterRelation = relationManager.getMasterRelation(designEntity.getFormId(), tableId);
            List<Long> slaveTableIdList = masterRelation.stream().map(WfFormTableRelationEntity::getSlaveTableId).collect(Collectors.toList());
            List<Long> slaveColumnIdList = masterRelation.stream().map(WfFormTableRelationEntity::getSlaveColumnId).collect(Collectors.toList());
            Map<Long, String> tableMap = tableManager.listByIds(slaveTableIdList).stream().collect(Collectors.toMap(BaseEntity::getId, WfFormTableEntity::getTableName));
            Map<Long, String> columnMap = columnManager.listByIds(slaveColumnIdList).stream().collect(Collectors.toMap(BaseEntity::getId, WfFormColumnEntity::getColumnName));
            for (WfFormTableRelationEntity relationEntity : masterRelation) {
                //级联删除, 删除从表数据
                operationMapper.delByColumnName(tableMap.get(relationEntity.getSlaveTableId()), columnMap.get(relationEntity.getSlaveColumnId()), dataId);
            }

        }
    }


    @Override
    public PageInfo<Map<String, Object>> listOperation(OperationListQuery query) {
        WfFormDesignEntity designEntity = designManager.getById(query.getDesignId());
        Long tableId = designEntity.getTableId();
        //表字段信息
        List<WfFormColumnEntity> columnList = columnManager.getColumnList(tableId);
        //关联关系
        List<Long> columnIdList = columnList.stream().map(BaseEntity::getId).collect(Collectors.toList());
        List<WfFromColumnLinkEntity> linkList = linkManager.getByColumnId(columnIdList);
        //主表信息
        WfFormTableEntity masterTable = tableManager.getById(tableId);
        //外键关联
        Map<Long, WfLinkColumnDTO> linkTableMap = bulidColumnLinkTableMap(linkList);

        //是否有 一对多关联字段
        boolean isOneToMany = false;
        long count = query.getTableColumnList().stream().filter(OperationTableColumnDTO::getVirtualColumn).count();
        if (count > 0) {
            isOneToMany = true;
        }

        Map<String, Object> selectMap = this.buildSelectAndGroupByFields(query.getTableColumnList(), linkTableMap);
        //构建查询字段
        String selectFields = selectMap.get("selectField").toString();
        Map<String, String> dataTypeMap = (Map<String, String>) selectMap.get("dataTypeMap");

        //构建 left语句
        List<JoinTableDTO> joinInfo = new ArrayList<>();
        this.buildLeftJoin(masterTable, joinInfo, selectMap.get("tableNameSet"));

        //构建查询条件
        List<OperationFilterDTO> filterList = this.buildFilter(query, masterTable);

        //构建groupBy
        String groupBySql = null;
        if (isOneToMany) {
            groupBySql = selectMap.get("groupBy").toString();
        }

        //排序list
        List<WfFormColumnEntity> orderNoColumnList = columnList.stream().filter(item -> null != item.getOrderNo() && item.getOrderNo() != 0)
                .sorted(Comparator.comparing(WfFormColumnEntity::getOrderNo)).collect(Collectors.toList());

        //构建 orderSql
        String orderSql = this.buildOrderBySql(masterTable.getTableName(), orderNoColumnList, query.getOrderList());

        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<Map<String, Object>> resultList = operationMapper.pageList(masterTable.getTableName(), selectFields,
                joinInfo, filterList, groupBySql, orderSql);
        Map<Triple<String, String, String>, Object> convertDataMap = ExcelDataUtil.getAllConvertData();

        //遍历数据, 如果是虚拟字段有格式化的,需要格式化并返回
        for (Map<String, Object> map : resultList) {
            Set<String> keySet = map.keySet();
            for (String key : keySet) {
                if (dataTypeMap.containsKey(key)) {
                    String format = dataTypeMap.get(key);
                    map.put(key, formatVirtualColumnValue(map.get(key).toString(), format));
                } else {
                    Object object = FormUtil.convertData(convertDataMap, columnList, key, map.get(key));
                    map.put(key, object);
                }
            }
            //组装link新字段
            buildLinkNewColumn(linkList, map);
        }
        return PageInfo.of(resultList);
    }

    @Override
    public PageInfo<Map<String, Object>> linkList(LinkListQuery query) {
        WfFromColumnLinkEntity linkEntity = linkManager.getByColumnId(query.getColumnId());
        List<WfLinkQuerysDTO> querysList = JSONArray.parseArray(linkEntity.getLinkFromQuerys(), WfLinkQuerysDTO.class);
        List<WfLinkWheresDTO> wheresList = new ArrayList<>();

        //构建查询sql
        String selectFiledSql = this.buildLinkSelectFiled(querysList);
        String tableName = this.buildLinkFrom(querysList);
        if (StrUtil.isNotBlank(linkEntity.getLinkFormWheres())) {
            //关联条件不为空
            wheresList = JSONArray.parseArray(linkEntity.getLinkFormWheres(), WfLinkWheresDTO.class);
            this.buildLinkWhere(wheresList);
        }
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<Map<String, Object>> resultList = operationMapper.linkList(tableName, selectFiledSql, wheresList);
        return PageInfo.of(resultList);
    }

    /**
     * 获取数据详情
     *
     * @param designId designId
     * @param dataId   数据id
     */
    @Override
    public Map<String, Object> getOperation(Long designId, Long dataId) {
        WfFormDesignEntity designEntity = designManager.getById(designId);
        Long tableId = designEntity.getTableId();
        WfFormTableEntity tableEntity = tableManager.getById(tableId);
        List<WfFormColumnEntity> columnList = columnManager.getColumnList(tableId);
        Map<String, Object> map = operationMapper.getOperation(tableEntity.getTableName(), dataId);
        List<Long> columnIdList = columnList.stream().map(BaseEntity::getId).collect(Collectors.toList());
        List<WfFromColumnLinkEntity> linkList = linkManager.getByColumnId(columnIdList);

        if (null != map) {
            //组装link新字段
            buildLinkNewColumn(linkList, map);
            return map;
        }
        return new HashMap<>(16);
    }

    /**
     * 导出模板 名称
     *
     * @param designId 设计表id
     * @return
     */
    @Override
    public String exportTemplate(Long designId) {
        WfFormDesignEntity designEntity = designManager.getById(designId);
        return designEntity.getFormDesignName();
    }

    @Override
    public Map<String, List<List<String>>> exportTemplateData(OperationListQuery query) {
        WfFormDesignEntity designEntity = designManager.getById(query.getDesignId());
        Long tableId = designEntity.getTableId();
        //表字段信息
        List<WfFormColumnEntity> columnList = columnManager.getColumnList(tableId);
        //key字段名,value 字段描述
        Map<String, String> columnMap = columnList.stream().collect(Collectors.toMap(WfFormColumnEntity::getColumnName, WfFormColumnEntity::getName));

        //查询数据
        PageInfo<Map<String, Object>> pageInfo = listOperation(query);
        List<Map<String, Object>> list = pageInfo.getList();

        Map<String, List<List<String>>> resultMap = new HashMap<>(2);
        //返回表头信息
        List<List<String>> headList = new ArrayList<>();
        //返回数据信息
        List<List<String>> dataList = new ArrayList<>();

        //组装表头和数据
        Set<String> head = new HashSet<>();
        for (int i = 0; i < list.size(); i++) {
            Map<String, Object> map = list.get(i);
            List<String> data = new ArrayList<>();
            for (String s : map.keySet()) {
                head.add(columnMap.get(s));
                data.add(String.valueOf(map.get(s)));
            }
            dataList.add(data);
        }
        headList = head.stream().map(Arrays::asList).collect(Collectors.toList());
        resultMap.put("headList", headList);
        resultMap.put("dataList", dataList);
        return resultMap;
    }

    //############################### 私有函数 ###############################

    /**
     * 构建关联表 查询字段
     *
     * @param querysList
     * @return
     */
    private String buildLinkSelectFiled(List<WfLinkQuerysDTO> querysList) {
        StringBuilder selectBuilder = new StringBuilder();
        for (WfLinkQuerysDTO querysDTO : querysList) {
            selectBuilder.append(querysDTO.getLinkTableName())
                    .append(StrUtil.DOT)
                    .append(querysDTO.getLinkColumnName())
                    .append(StrUtil.COMMA);
        }
        return selectBuilder.substring(0, selectBuilder.length() - 1);
    }

    /**
     * 构建关联表 form语句
     *
     * @return
     */
    private String buildLinkFrom(List<WfLinkQuerysDTO> querysList) {
        return querysList.get(0).getLinkTableName();
    }

    /**
     * 构建关联表 where语句
     *
     * @return
     */
    private void buildLinkWhere(List<WfLinkWheresDTO> wheresList) {
        if (CollUtil.isEmpty(wheresList)) {
            return;
        }
        for (WfLinkWheresDTO wheresDTO : wheresList) {
            //todo 判断value值类型,
            if (FieldFilterConstant.LIKE.equals(wheresDTO.getFilterType())) {
                wheresDTO.setValue("%" + wheresDTO.getValue() + "%");
            }
            if (FieldFilterConstant.IN.equals(wheresDTO.getFilterType())) {
                wheresDTO.setValueList(Arrays.asList(wheresDTO.getValue().split(StrUtil.COMMA)));
            }
        }
    }

    /**
     * 构建 排序 sql
     *
     * @param orderList
     * @return
     */
    private String buildOrderBySql(String tableName, List<WfFormColumnEntity> orderNoColumnList, List<OperationOrderDTO> orderList) {
        StringBuilder orderBuilder = new StringBuilder();
        if(CollUtil.isNotEmpty(orderList)){
            //搜索时的排序
            for (OperationOrderDTO orderDto : orderList) {
                orderBuilder.append(orderDto.getTableName())
                        .append(StrUtil.DOT)
                        .append(orderDto.getColumnName())
                        .append(" ")
                        .append(orderDto.getOrderType())
                        .append(StrUtil.COMMA);
            }
        }
        //配置的排序
        for (WfFormColumnEntity column : orderNoColumnList) {
            orderBuilder.append(tableName)
                    .append(StrUtil.DOT)
                    .append(column.getColumnName())
                    .append(" ")
                    .append(column.getOrderType())
                    .append(StrUtil.COMMA);
        }

        //最终的默认排序
        orderBuilder.append(tableName)
                .append(StrUtil.DOT)
                .append("create_time")
                .append(" ")
                .append("desc")
                .append(StrUtil.COMMA);
        return orderBuilder.substring(0, orderBuilder.length() - 1);
    }

    /**
     * 列表查询 - 构建过滤条件
     *
     * @param filterList
     */
    private List<OperationFilterDTO> buildFilter(OperationListQuery query, WfFormTableEntity table) {
        List<OperationFilterDTO> filterList = CollUtil.isEmpty(query.getFilterList()) ? new ArrayList<>() : query.getFilterList();
        //如果为子表查询,则需要拼接主表id作为搜索条件
        if (FormEnum.ZERO.getValue().equals(query.getIsMaster())) {
            //查询子表,  自动拼接主表字段
            WfFormDesignEntity designEntity = designManager.getById(query.getDesignId());
            WfFormTableRelationEntity relationEntity = relationManager.getMasterTable(designEntity.getFormId(), designEntity.getTableId(), null);
            WfFormColumnEntity columnEntity = columnManager.getById(relationEntity.getSlaveColumnId());
            //添加主表搜索条件
            OperationFilterDTO dto = new OperationFilterDTO();
            dto.setColumnName(columnEntity.getColumnName());
            dto.setTableName(table.getTableName());
            dto.setColumnValue(query.getMasterId());
            dto.setFilterType(FieldFilterConstant.EQUAL);
            filterList.add(dto);
        }
        if (CollUtil.isNotEmpty(filterList)) {
            filterList.forEach(filter -> {
                if (FieldFilterConstant.LIKE.equals(filter.getFilterType())) {
                    filter.setColumnValue("%" + filter.getColumnValue() + "%");
                }
                if (FieldFilterConstant.OR.equals(filter.getFilterType())) {
                    Set<String> collect = filter.getColumnValueList().stream().map(item -> {
                        item = "%" + item + "%";
                        return item;
                    }).collect(Collectors.toSet());
                    filter.setColumnValueList(collect);
                }
            });
        }
        return filterList;
    }

    /**
     * 列表查询 - 构建连接信息
     *
     * @param masterTable
     */
    private void buildLeftJoin(WfFormTableEntity masterTable, List<JoinTableDTO> joinInfo, Object obj) {
        Set<String> tableNameSet = (Set<String>) obj;
        //关联关系left join
        buildRelationLeftJoin(masterTable, joinInfo, tableNameSet);
        //外键  left join
        buildForeignKeyLeftJoin(masterTable, joinInfo, tableNameSet);
    }

    /**
     * 构建关联关系的left join语句
     */
    private void buildRelationLeftJoin(WfFormTableEntity masterTable, List<JoinTableDTO> joinInfo, Set<String> tableNameSet) {
        //查询关联表 是否有一对一关联或者一对多关联
        List<WfFormTableRelationEntity> salverTableList = relationManager.getMasterRelation(masterTable.getFormId(), masterTable.getId());

        if (CollUtil.isEmpty(salverTableList)) {
            return;
        }
        //关联字段 id 集合
        Set<Long> columnIdList = new HashSet<>();
        for (WfFormTableRelationEntity tableEntity : salverTableList) {
            columnIdList.add(tableEntity.getMasterColumnId());
            columnIdList.add(tableEntity.getSlaveColumnId());
        }
        Map<Long, String> columnNameMap = columnManager.listByIds(columnIdList).stream().collect(Collectors.toMap(WfFormColumnEntity::getId, WfFormColumnEntity::getColumnName));

        for (WfFormTableRelationEntity salverTable : salverTableList) {
            WfFormTableEntity salverTableEntity = tableManager.getById(salverTable.getSlaveTableId());
            if (!tableNameSet.contains(salverTableEntity.getTableName())) {
                //不包含搜索条件 则不连表
                continue;
            }
            JoinTableDTO joinTable = new JoinTableDTO();
            joinTable.setJoinTableName(salverTableEntity.getTableName());
            // 根据配置动态拼接JOIN的关联条件。
            StringBuilder conditionBuilder = new StringBuilder();
            conditionBuilder
                    .append(masterTable.getTableName())
                    .append(StrUtil.DOT)
                    .append(columnNameMap.get(salverTable.getMasterColumnId()))
                    .append(" = ")
                    .append(salverTableEntity.getTableName())
                    .append(StrUtil.DOT)
                    .append(columnNameMap.get(salverTable.getSlaveColumnId()));
            joinTable.setJoinCondition(conditionBuilder.toString());
            joinInfo.add(joinTable);
        }
    }

    /**
     * 构建 外键关系的 left join 语句
     *
     * @return
     */
    private void buildForeignKeyLeftJoin(WfFormTableEntity masterTable, List<JoinTableDTO> joinInfo, Set<String> tableNameSet) {

        List<WfFormColumnEntity> columnList = columnManager.getColumnList(masterTable.getId());
        List<Long> columnIdList = columnList.stream().map(BaseEntity::getId).collect(Collectors.toList());
        List<WfFromColumnLinkEntity> linkList = linkManager.getByColumnId(columnIdList);
        if (CollUtil.isEmpty(linkList)) {
            return;
        }
        for (WfFromColumnLinkEntity entity : linkList) {
            JoinTableDTO joinTable = new JoinTableDTO();
            List<WfLinkQuerysDTO> querysDTOList = JSONArray.parseArray(entity.getLinkFromQuerys(), WfLinkQuerysDTO.class);
            WfLinkQuerysDTO dto = querysDTOList.stream().filter(item -> FormEnum.ONE.getValue().equals(item.getIsMaster())).collect(Collectors.toList()).get(0);
            if (!tableNameSet.contains(dto.getLinkTableName())) {
                //不包含搜索条件 则不连表
                continue;
            }
            joinTable.setJoinTableName(dto.getLinkTableName() + " " + dto.getLinkTableName());
            // 根据配置动态拼接JOIN的关联条件。
            StringBuilder conditionBuilder = new StringBuilder();
            conditionBuilder
                    .append(masterTable.getTableName())
                    .append(StrUtil.DOT)
                    .append(dto.getColumnName())
                    .append(" = ")
                    .append(dto.getLinkTableName())
                    .append(StrUtil.DOT)
                    .append(dto.getLinkColumnName());
            joinTable.setJoinCondition(conditionBuilder.toString());
            joinInfo.add(joinTable);
        }
    }


    /**
     * 列表查询 - 构建主表/从表 查询条件
     *
     * @return
     */
    private Map<String, Object> buildSelectAndGroupByFields(List<OperationTableColumnDTO> tableColumnList, Map<Long, WfLinkColumnDTO> linkTableMap) {
        Map<String, Object> map = new HashMap<>(16);
        StringBuilder selectFieldBuilder = new StringBuilder();
        StringBuilder groupByBuilder = new StringBuilder();
        Set<String> tableNameSet = new HashSet<>();
        Map<String, String> dataTypeMap = new HashMap<>(16);
        for (OperationTableColumnDTO column : tableColumnList) {
            //拼接聚合字段
            if (column.getVirtualColumn()) {
                WfFormVirtualColumnEntity virtualColumnEntity = virtualColumnManager.getById(column.getColumnId());
                WfFormTableEntity tableEntity = tableManager.getById(virtualColumnEntity.getAggregationTableId());
                WfFormColumnEntity columnEntity = columnManager.getById(virtualColumnEntity.getAggregationColumnId());
                selectFieldBuilder
                        .append(AggregationTypeConstant.getAggregationFunction(virtualColumnEntity.getAggregationType()))
                        .append("(")
                        .append(tableEntity.getTableName())
                        .append(StrUtil.DOT)
                        .append(columnEntity.getColumnName())
                        .append(") ")
                        .append(" AS ")
                        .append(virtualColumnEntity.getColumnName())
                        .append(StrUtil.COMMA);
                tableNameSet.add(tableEntity.getTableName());
                if (StrUtil.isNotBlank(virtualColumnEntity.getDataType())) {
                    dataTypeMap.put(virtualColumnEntity.getColumnName(), virtualColumnEntity.getDataType());
                }
            } else {
                String tableName = column.getTableName();
                String columnName = column.getColumnName();
                //判断当前字段是否被 外键 显示字段覆盖
                if (ObjectUtil.isNotEmpty(linkTableMap.get(column.getColumnId()))) {
                    tableName = linkTableMap.get(column.getColumnId()).getTableName();
                    columnName = linkTableMap.get(column.getColumnId()).getColumnName();
                }
                selectFieldBuilder.append(tableName)
                        .append(StrUtil.DOT)
                        .append(columnName)
                        .append(" AS ")
                        .append(column.getColumnName())
                        .append(StrUtil.COMMA);
                groupByBuilder.append(tableName)
                        .append(StrUtil.DOT)
                        .append(columnName)
                        .append(StrUtil.COMMA);
                tableNameSet.add(tableName);
            }
        }
        map.put("selectField", selectFieldBuilder.substring(0, selectFieldBuilder.length() - 1));
        map.put("groupBy", groupByBuilder.substring(0, groupByBuilder.length() - 1));
        map.put("tableNameSet", tableNameSet);
        map.put("dataTypeMap", dataTypeMap);
        return map;
    }


    /**
     * 构建列外键 显示关联关系
     *
     * @param tableId
     * @return map key: columnId value: linkTableName
     */
    private Map<Long, WfLinkColumnDTO> bulidColumnLinkTableMap(List<WfFromColumnLinkEntity> linkList) {
        Map<Long, WfLinkColumnDTO> columnLinkTableMap = new HashMap<>(16);
        if (CollUtil.isNotEmpty(linkList)) {
            for (WfFromColumnLinkEntity entity : linkList) {
                String fromQuerys = entity.getLinkFromQuerys();
                List<WfLinkQuerysDTO> querysList = JSONArray.parseArray(fromQuerys, WfLinkQuerysDTO.class);
                for (WfLinkQuerysDTO query : querysList) {
                    if (FormEnum.ZERO.getValue().equals(query.getIsMaster())) {
                        WfLinkColumnDTO linkColumnDTO = new WfLinkColumnDTO();
                        linkColumnDTO.setTableName(query.getLinkTableName());
                        linkColumnDTO.setColumnName(query.getLinkColumnName());
                        columnLinkTableMap.put(query.getColumnId(), linkColumnDTO);
                    }
                }
            }
        }
        return columnLinkTableMap;
    }

    /**
     * 构建数据表 data
     *
     * @param tableData  保存/跟新的表数据
     * @param columnList 表的字段列表
     * @param forUpdate  是否为更新操作
     * @return
     */
    private List<ColumnDataDTO> buildTableData(JSONObject tableData, List<WfFormColumnEntity> columnList, boolean forUpdate) {
        List<ColumnDataDTO> columnDataList = new LinkedList<>();
        columnList.forEach(column -> {
            Object value = this.getColumnValue(tableData, column);
            if (forUpdate) {
                //跟新
                if (ObjectDefaultColumnConstant.ID.equals(column.getColumnName()) && null == value) {
                    //跟新的时候 主键为空,则报错
                    Asserts.fail("[sys.msg.failed]");
                }
                if (ObjectDefaultColumnConstant.UPDATE_BY.equals(column.getColumnName()) ||
                        ObjectDefaultColumnConstant.UPDATE_TIME.equals(column.getColumnName())) {
                    //跟新的时候 如果是跟新时间/跟新用户 则添加空的ColumnDataDTO ,后续赋值默认值的时候会赋值上
                    columnDataList.add(new ColumnDataDTO(column, null));
                } else {
                    if (ObjectUtil.isNotEmpty(value)) {
                        //跟新的时候 如果原数据的值不为空,则需要添加ColumnDataDTO
                        //不然手写的sql 如果不赋值原数据,执行sql的时候会把不传参的数据全部置空
                        columnDataList.add(new ColumnDataDTO(column, value));
                    }
                }
            }
            //新增
            else {
                if (ObjectDefaultColumnConstant.DEFAULT_COLUMN_LIST.contains(column.getColumnName())) {
                    //默认字段 ==> 不处理,赋默认值
                    columnDataList.add(new ColumnDataDTO(column, null));
                } else {
                    if (FormEnum.ONE.getValue().equals(column.getValidIsNull()) && null == value) {
                        //非主键,必填的时候为空,则报错
                        Asserts.fail("[sys.msg.failed]");
                    }
                    columnDataList.add(new ColumnDataDTO(column, value));
                }
            }
        });
        return columnDataList;
    }


    /**
     * 构建 新增/更新表sql 表字段
     *
     * @param columnDataList
     * @return
     */
    private String makeColumnNames(List<ColumnDataDTO> columnDataList) {
        StringBuilder sb = new StringBuilder();
        for (ColumnDataDTO columnData : columnDataList) {
            sb.append(columnData.getColumn().getColumnName()).append(StrUtil.COMMA);
        }
        return sb.substring(0, sb.length() - 1);
    }


    /**
     * 验证 字段 规则
     *
     * @param dto
     */
    private void checkColumnEncodedRule(ColumnDataDTO dto) {
        String encodedRule = dto.getColumn().getEncodedRule();
        if (StrUtil.isNotBlank(encodedRule)) {
            List<ColumnRuleDto> ruleDtos = JSONArray.parseArray(encodedRule, ColumnRuleDto.class);
            for (ColumnRuleDto ruleDto : ruleDtos) {
                if (!ReUtil.isMatch(ruleDto.getCron(), dto.getColumnValue().toString())) {
                    //不匹配正则
                    Asserts.fail(ruleDto.getMessage());
                }
            }
        }
    }

    /**
     * 基础字段赋值 和 有默认值的 赋值
     *
     * @param columnData 字段
     */
    private void makeupColumnValue(ColumnDataDTO columnData, String bmpKey, boolean isUpdate, Long createId) {
        if (isUpdate) {
            if (ObjectDefaultColumnConstant.UPDATE_BY.equals(columnData.getColumn().getColumnName())) {
                columnData.setColumnValue(LoginUserUtil.getUserInfo().getLoginUserVO().getId());
            } else if (ObjectDefaultColumnConstant.UPDATE_TIME.equals(columnData.getColumn().getColumnName())) {
                columnData.setColumnValue(LocalDateTime.now());
            }
            return;
        }
        if (FormEnum.ONE.getValue().equals(columnData.getColumn().getPrimaryKey())) {
            if (null == createId) {
                columnData.setColumnValue(IdWorker.getId());
            } else {
                columnData.setColumnValue(createId);
            }
        } else if (ObjectDefaultColumnConstant.ORG_ID.equals(columnData.getColumn().getColumnName())) {
            columnData.setColumnValue(LoginUserUtil.getUserInfo().getLoginUserVO().getLoginOrgId());
        } else if (ObjectDefaultColumnConstant.CREATE_BY.equals(columnData.getColumn().getColumnName())) {
            columnData.setColumnValue(LoginUserUtil.getUserInfo().getLoginUserVO().getId());
        } else if (ObjectDefaultColumnConstant.CREATE_TIME.equals(columnData.getColumn().getColumnName())) {
            columnData.setColumnValue(LocalDateTime.now());
        } else if (ObjectDefaultColumnConstant.DELETED.equals(columnData.getColumn().getColumnName())) {
            columnData.setColumnValue(FormEnum.ZERO.getValue());
        } else if (ObjectDefaultColumnConstant.BMP_KEY.equals(columnData.getColumn().getColumnName())) {
            columnData.setColumnValue(bmpKey);
        } else if (ObjectDefaultColumnConstant.BMP_STATUS.equals(columnData.getColumn().getColumnName())) {
            // todo 赋值工作流status
            columnData.setColumnValue(null);
        } else if (FieldKindConstant.NOW_TIME.equals(columnData.getColumn().getFieldKind())) {
            //字段类型 - nowTime
            if(StrUtil.isNotBlank(columnData.getColumn().getDataType())){
                columnData.setColumnValue( DateUtil.format(LocalDateTime.now(), columnData.getColumn().getDataType()));
            }else{
                columnData.setColumnValue(LocalDateTime.now());
            }
        } else if (FieldKindConstant.NOW_USER.equals(columnData.getColumn().getFieldKind())) {
            //字段类型 - user
            columnData.setColumnValue(LoginUserUtil.getUserInfo().getLoginUserVO().getId());
        } else if (FieldKindConstant.NOW_ORGANIZATION.equals(columnData.getColumn().getFieldKind())) {
            //字段类型 - organization
            columnData.setColumnValue(LoginUserUtil.getUserInfo().getLoginUserVO().getLoginOrgCode());
        } else if (FieldKindConstant.NOW_POST.equals(columnData.getColumn().getFieldKind())) {
            //字段类型 - post
            columnData.setColumnValue(LoginUserUtil.getUserInfo().getLoginUserVO().getCurPostId());
        } else if (FieldKindConstant.NOW_LEVEL.equals(columnData.getColumn().getFieldKind())) {
            //字段类型 - level
            columnData.setColumnValue(LoginUserUtil.getUserInfo().getLoginUserVO().getLevelId());
        } else if(FieldKindConstant.ENVIRONMENT.equals(columnData.getColumn().getFieldKind())){
            //环境变量
            if(StrUtil.isNotBlank(columnData.getColumn().getDataType())){
                LoginUserVO userVO = LoginUserUtil.getUserInfo().getLoginUserVO();
                // 将Java对象转换为JSON字符串
                String jsonString = JSON.toJSONString(userVO);
                // 将JSON字符串转换为Map
                JSONObject jsonObject = JSON.parseObject(jsonString);
                Map<String, Object> personMap = jsonObject.getInnerMap();

                columnData.setColumnValue(personMap.get(columnData.getColumn().getDataType()));
            }else{
                columnData.setColumnValue(null);
            }

        } else if(FieldKindConstant.CODE.equals(columnData.getColumn().getFieldKind())){
            //自定义编码
            if(StrUtil.isNotBlank(columnData.getColumn().getDataType())){
                codeRuleHandler.execute(Long.valueOf(columnData.getColumn().getDataType()),null,1);
            }else{
                columnData.setColumnValue(null);
            }
        }
        else if (StrUtil.isNotBlank(columnData.getColumn().getColumnDefault()) && ObjectUtil.isEmpty(columnData.getColumnValue())) {
            //如果有默认值,但是默认值为空,则赋默认值
            Object value = this.convertToTypeValue(
                    columnData.getColumn(), columnData.getColumn().getColumnDefault());
            columnData.setColumnValue(value);
        } else if (StrUtil.isBlank(columnData.getColumn().getColumnDefault()) && ObjectUtil.isEmpty(columnData.getColumnValue())) {
            columnData.setColumnValue(null);
        }
    }


    /**
     * 将字符型字段值转换为与参数字段类型匹配的字段值
     *
     * @param column
     * @param defaultValue
     * @return
     */
    public Serializable convertToTypeValue(WfFormColumnEntity column, String defaultValue) {
        if (ObjectFieldType.LONG.equals(column.getObjectFieldType())) {
            return Long.valueOf(defaultValue);
        } else if (ObjectFieldType.INTEGER.equals(column.getObjectFieldType())) {
            return Integer.valueOf(defaultValue);
        }
        return defaultValue;
    }


    private Object getColumnValue(JSONObject tableData, WfFormColumnEntity column) {
        Object value = tableData.get(column.getColumnName());
        if (value != null) {
            if (ObjectFieldType.LONG.equals(column.getObjectFieldType())) {
                value = Long.valueOf(value.toString());
            } else if (ObjectFieldType.DATE.equals(column.getObjectFieldType())) {
                value = Convert.toLocalDateTime(value);
            }
        }
        return value;
    }


    /**
     * 保存单个数据
     *
     * @param designId id
     * @param data     保存数据
     */
    public Long addOperation(Long tableId, JSONObject data) {
        WfFormTableEntity tableEntity = tableManager.getById(tableId);

        List<Object> columnValueList = new LinkedList<>();

        //构建 新增/跟新 sql表列名
        String columnNames = null;
        long createId = IdWorker.getId();
        //构建单个insert 插入信息
        columnNames = buildInsertInfo(tableEntity, data, columnNames, columnValueList, createId);
        //插入数据
        operationMapper.insert(tableEntity.getTableName(), columnNames, columnValueList);
        return createId;
    }

    /**
     * 保存 多个数据
     *
     * @param designId id
     * @param data     保存数据
     */
    public List<Long> addOperationBatch(Long tableId, JSONArray jsonArray) {
        List<Long> createIdList = new ArrayList<>();
        WfFormTableEntity tableEntity = tableManager.getById(tableId);
        String columnNames = null;
        List<List<Object>> columnValueList = new ArrayList<>();
        for (Object object : jsonArray) {
            JSONObject data = (JSONObject) object;
            //构建 新增/跟新 sql表列名
            long createId = IdWorker.getId();
            createIdList.add(createId);
            List<Object> rowColumnValueList = new LinkedList<>();
            //构建单个insert 插入信息
            columnNames = buildInsertInfo(tableEntity, data, columnNames, rowColumnValueList, createId);
            columnValueList.add(rowColumnValueList);
        }

        //插入数据
        operationMapper.insertBatch(tableEntity.getTableName(), columnNames, columnValueList);
        return createIdList;
    }

    /**
     * 构建单个insert 插入信息
     *
     * @param tableEntity
     * @param data
     * @param columnNames
     * @param columnValueList
     */
    private String buildInsertInfo(WfFormTableEntity tableEntity, JSONObject data, String columnNames, List<Object> columnValueList, long createId) {
        //获取表所有字段
        List<WfFormColumnEntity> columnList = columnManager.getColumnList(tableEntity.getId());
        //data=> 构建column
        List<ColumnDataDTO> columnDataList = this.buildTableData(data, columnList, false);

        //构建 新增/跟新 sql表列名
        columnNames = this.makeColumnNames(columnDataList);
        for (ColumnDataDTO columnData : columnDataList) {
            //赋默认值
            this.makeupColumnValue(columnData, tableEntity.getBmpKey(), false, createId);
            //验证字段规则,正则
            this.checkColumnEncodedRule(columnData);
            columnValueList.add(columnData.getColumnValue());
        }
        return columnNames;
    }


    /**
     * 跟新单个数据
     *
     * @param designId
     * @param data
     */
    private void updateOperation(Long designId, JSONObject data) {
        WfFormDesignEntity designEntity = designManager.getById(designId);
        Long tableId = designEntity.getTableId();
        WfFormTableEntity tableEntity = tableManager.getById(tableId);

        //获取表所有字段
        List<WfFormColumnEntity> columnList = columnManager.getColumnList(tableId);
        //data=> 构建column
        List<ColumnDataDTO> columnDataList = this.buildTableData(data, columnList, true);

        for (ColumnDataDTO columnData : columnDataList) {
            if (FormEnum.ONE.getValue().equals(columnData.getColumn().getIsDefault())) {
                //默认字段 赋默认值
                this.makeupColumnValue(columnData, tableEntity.getBmpKey(), true, null);
                //验证字段规则,正则
                this.checkColumnEncodedRule(columnData);
            } else {
                //不是默认字段
            }

        }
        operationMapper.updateById(tableEntity.getTableName(), columnDataList);
    }

    /**
     * 格式化虚拟字段
     *
     * @param value
     * @param format
     * @return
     */
    private String formatVirtualColumnValue(String value, String format) {
        // 检查是否是日期格式化
        if (isDate(value)) {
            return DateUtil.format(DateUtil.parse(value), format);
        }
        // 检查是否是BigDecimal格式化
        if (NumberUtil.isNumber(value)) {
            return formatNumber(value, format);
        }
        return value;
    }

    /**
     * 是否为日期
     *
     * @param date
     * @return
     */
    private boolean isDate(String date) {
        DateUtil.parse(date);
        return true;
    }

    /**
     * 格式化 数字
     *
     * @param value
     * @param format
     * @return
     */
    public static String formatNumber(String value, String format) {

        //格式数字类型不正确,直接返回
        if (!com.wsoft.utils.NumberUtil.isValidDecimalFormatString(format)) {
            return value;
        }

        // 解析格式字符串，获取精度和刻度
        String[] parts = format.split(",");
        int precision = Integer.parseInt(parts[0]);
        int scale = Integer.parseInt(parts[1]);

        // 将字符串数值转换为 BigDecimal
        BigDecimal number = new BigDecimal(value);

        // 设置精度和刻度
        number = number.setScale(scale, RoundingMode.HALF_UP);

        // 格式化输出
        return String.format("%." + precision + "f", number);
    }


    /**
     * 构建link表 返回新的绑定字段
     *
     * @param tableId
     * @param map
     */
    private void buildLinkNewColumn(List<WfFromColumnLinkEntity> linkList, Map<String, Object> map) {
        //table下 所有字段id集合
        if (CollUtil.isEmpty(linkList)) {
            return;
        }
        for (WfFromColumnLinkEntity linkEntity : linkList) {
            if (StrUtil.isNotBlank(linkEntity.getLinkFromQuerys())) {
                List<WfLinkQuerysDTO> queryList = JSONArray.parseArray(linkEntity.getLinkFromQuerys(), WfLinkQuerysDTO.class);
                WfFormColumnEntity columnEntity = columnManager.getById(linkEntity.getColumnMasterId());
                Object value = map.get(columnEntity.getColumnName());
                //获取关联关系,并组装新字段,存入原map
                map.putAll(linkQuerySelect(queryList, value));
            }
        }
    }


    /**
     * 关联关系,查询数据库
     *
     * @param queryList
     * @param value
     * @return
     */
    private Map<String, Object> linkQuerySelect(List<WfLinkQuerysDTO> queryList, Object value) {
        Map<String, Object> resultMap = new HashMap<>(16);

        List<WfLinkQuerysDTO> collect = queryList.stream().filter(item -> FormEnum.ONE.getValue().equals(item.getIsMaster())).collect(Collectors.toList());
        if (CollUtil.isEmpty(collect) || collect.size() > 1) {
            Asserts.fail("[关联表单配置错误]");
        }
        WfLinkQuerysDTO masterLinkDto = collect.get(0);
        String tableName = masterLinkDto.getLinkTableName();
        String whereColumnName = masterLinkDto.getLinkColumnName();

        //要显示的字段名
        List<String> selectColumnList = collect.stream().map(WfLinkQuerysDTO::getShowColumnName).collect(Collectors.toList());
        if (StrUtil.isBlank(tableName) || CollUtil.isEmpty(selectColumnList)) {
            return resultMap;
        }

        //查询主字段关联表数据
        List<Map<String, Object>> recordList = operationMapper.linkQuery(tableName, whereColumnName, selectColumnList, value);
        if (CollUtil.isEmpty(recordList) || recordList.size() > 1) {
            //没有数据 或者有多条数据
            Asserts.fail("[wform.configuration.error]");
        }
        Map<String, Object> map = recordList.get(0);
        for (WfLinkQuerysDTO querysDTO : queryList) {
            if (map.containsKey(querysDTO.getShowColumnName())) {
                //新增返回字段,拼接新后缀
                resultMap.put(querysDTO.getColumnName() + LINK_COLUMN_SUFFIX, map.get(querysDTO.getShowColumnName()));
            }
        }

        return resultMap;
    }


}
